package com.coderly.onlinegallerysharingplatform.common.oss.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import com.coderly.onlinegallerysharingplatform.common.convention.errorcode.ErrorCode;
import com.coderly.onlinegallerysharingplatform.common.convention.exception.BizException;
import com.coderly.onlinegallerysharingplatform.model.dao.entity.PictureDO;
import com.coderly.onlinegallerysharingplatform.model.dto.resp.pic.PicOperationResult;
import com.coderly.onlinegallerysharingplatform.common.oss.config.TencentOSSClientConfig;
import com.coderly.onlinegallerysharingplatform.common.oss.strategy.FileStrategy;
import com.coderly.onlinegallerysharingplatform.common.oss.service.FileService;
import com.coderly.onlinegallerysharingplatform.service.PictureService;
import com.coderly.onlinegallerysharingplatform.toolkit.ExceptionTrowUtils;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.ciModel.persistence.CIObject;
import com.qcloud.cos.model.ciModel.persistence.ImageInfo;
import com.qcloud.cos.model.ciModel.persistence.ProcessResults;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
@Deprecated
public class FileServiceImpl implements FileService {

    @Resource
    private TencentOSSClientConfig tencentOSSClientConfig;
    @Resource
    private FileStrategy fileStrategy;
    @Resource
    private PictureService pictureService;

    /**
     * 上传图片
     *
     * @param multipartFile    图片
     * @param uploadPathPrefix 用户专属上传前缀
     * @return
     */
    @Override
    public PicOperationResult uploadPicture(MultipartFile multipartFile, String uploadPathPrefix) {
        // 校验图片
        validPicture(multipartFile);
        // 图片上传地址
        String uuid = RandomUtil.randomString(16);
        String originFilename = multipartFile.getOriginalFilename();
        // 添加业务前缀，方便管理图片，不使用原始文件名，增强安全性
        String uploadFilename = String.format("%s_%s.%s", DateUtil.formatDate(new Date()), uuid,
                FileUtil.getSuffix(originFilename));
        // 最终图片上传路径 = 用户专属前缀 + 系统自动生成文件名
        String uploadPath = String.format("/%s/%s", uploadPathPrefix, uploadFilename);
        File file = null;
        try {
            // 创建本地临时文件
            file = File.createTempFile(uploadPath, null);
            // 将用户上传的文件写入临时文件中
            multipartFile.transferTo(file);
            // 上传图片
            PutObjectResult putObjectResult = (PutObjectResult) fileStrategy.uploadPicture(file, uploadPath);
            // 获取上传图片进行处理后的返回结果
            ImageInfo imageInfo = putObjectResult.getCiUploadResult().getOriginalInfo().getImageInfo();
            // 获取图片处理结果
            ProcessResults processResults = putObjectResult.getCiUploadResult().getProcessResults();
            List<CIObject> objectList = processResults.getObjectList();
            if (CollUtil.isNotEmpty(objectList)) {
                // 获取压缩后的文件信息
                CIObject compressedCiObject = objectList.get(0); // 获取到压缩图片后的信息
                CIObject thumbnailCiObject = compressedCiObject;  // 缩略图默认等于压缩图
                if (objectList.size() > 1) {
                    thumbnailCiObject = objectList.get(1); // 获取到缩略图的信息
                }
                return buildResult(originFilename, compressedCiObject, thumbnailCiObject);
            }
            // TODO 待修改
            return null;
        } catch (Exception e) {
            log.error("图片上传到对象存储失败", e);
            throw new BizException(ErrorCode.SYSTEM_ERROR, "上传失败");
        } finally {
            this.deleteTempFile(file);
        }
    }

    /**
     * 封装返回结果用作保存数据库
     *
     * @param originFilename     原始文件名
     * @param compressedCiObject 压缩后的对象
     * @param thumbnailCiObject  缩略后的对象
     * @return
     */
    private PicOperationResult buildResult(String originFilename, CIObject compressedCiObject, CIObject thumbnailCiObject) {
        // 封装返回结果
        int picWidth = compressedCiObject.getWidth();
        int picHeight = compressedCiObject.getHeight();
        double picScale = NumberUtil.round(picWidth * 1.0 / picHeight, 2).doubleValue();
        PicOperationResult picOperationResult = PicOperationResult.builder()
                .url(tencentOSSClientConfig.getTencentOSSProperties().getHost() + "/" + compressedCiObject.getKey())
                .thumbnailUrl(tencentOSSClientConfig.getTencentOSSProperties().getHost() + "/" + thumbnailCiObject.getKey())
                .picName(FileUtil.mainName(originFilename))
                .picSize(compressedCiObject.getSize().longValue())
                .picWidth(picWidth)
                .picHeight(picHeight)
                .picScale(picScale)
                .picFormat(compressedCiObject.getFormat())
                .build();

        // 返回给前端
        return picOperationResult;

    }

    private void validPicture(MultipartFile multipartFile) {
        ExceptionTrowUtils.throwIf(multipartFile == null, ErrorCode.PARAMS_ERROR, "文件不能为空");
        // 1.校验文件大小
        long fileSize = multipartFile.getSize(); // 以字节为单位
        final long ONE_M = 1024 * 1024;
        ExceptionTrowUtils.throwIf(fileSize > 2 * ONE_M, ErrorCode.PARAMS_ERROR, "文件不能大于2MB");
        // 2. 校验文件后缀
        String fileSuffix = FileUtil.getSuffix(multipartFile.getOriginalFilename());
        // 允许上传的文件后缀
        final List<String> ALLOW_FORMAT_LIST = Arrays.asList("jpeg", "jpg", "png", "webp");
        ExceptionTrowUtils.throwIf(!ALLOW_FORMAT_LIST.contains(fileSuffix), ErrorCode.PARAMS_ERROR, "文件类型错误");

    }

    /**
     * 删除临时文件
     */
    public void deleteTempFile(File file) {
        if (file == null) {
            return;
        }
        // 删除临时文件
        boolean deleteResult = file.delete();
        if (!deleteResult) {
            log.error("file delete error, filepath = {}", file.getAbsolutePath());
        }
    }

    /**
     * 删除OSS中的图片
     *
     * @return
     */
    @Override
    public Boolean deletePicture(Long pictureId) {
        PictureDO oldPicture = pictureService.getById(pictureId);
        // url: https://ogsp-1323452891.cos.ap-beijing.myqcloud.com/public/1897256306043088898/2025-03-17_23i80jqdnGAehzoh.webp
        // thumbnail: https://ogsp-1323452891.cos.ap-beijing.myqcloud.com/public/1897256306043088898/2025-03-17_23i80jqdnGAehzoh_thumbnail.jpg
        String url = oldPicture.getUrl();
        // 获取 /public/1897256306043088898/2025-03-17_23i80jqdnGAehzoh
        int startIndex = url.indexOf("/public/");
        String path = url.substring(startIndex, url.lastIndexOf("."));
        return fileStrategy.deletePicture(path);
    }
}

